/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
#include "KeyWatcher.hpp"

CKeyWatcher::CKeyWatcher(std::string input, int writePipeInt, int readPipeInt):
  CThread(2),
  CSync(1,1),
  iInput(NULL),
  iKeyToWatch(0),
  iKeyBinded(false),
  iTestKey(false),
  iThreadRunning(true),
  iWritePipeInt(writePipeInt),
  iReadPipeInt(readPipeInt)
{
  iInput = fopen(input.c_str(),  "r");
  if(NULL == iInput) {

    std::ostringstream stm;
    stm << KMessageFailedToOpenKeyWatcher;
    write(iWritePipeInt,stm.str().c_str(),1);
  }else{
    std::ostringstream stm;
    stm << KMessageSuccesfullyOpenedKeyWatcher;
    write(iWritePipeInt,stm.str().c_str(),1);
  
    CThread::RunThread(0);
    CThread::RunThread(1);
  }
}

CKeyWatcher::~CKeyWatcher()
{
  iThreadRunning = false;

}



void CKeyWatcher::BindKeyToWatch()
{
  char data[16];

  while(1 != data[8] ||1 != data[12]){ 
    dPrint(1,"Reading...");
    ReadEventLine(data);
  }
  CSync::Lock();
  iKeyToWatch = val(data[10]);
  iKeyBinded = true;
  CSync::Unlock();
  dPrint(1,"Key binded");
}
  
  
  


int CKeyWatcher::ThreadFunction(const int aThreadNumber)
{
  
  if(aThreadNumber == 0){
    char data[16];
    while(iThreadRunning){
      dPrint(1,"thread 0...")
      if(iKeyBinded){
        
        
        ReadEventLine(data);
        if(1 == data[8]){ 
          if(1 == data[12]) { // PRESS
            CSync::Lock();
            if(!iTestKey){
              if(iKeyToWatch == val(data[10])){
                std::ostringstream stm;
                stm << KMessageEmergencyKeyPressed;
                write(iWritePipeInt,stm.str().c_str(),1);
                
              }
            }else{
              std::ostringstream stm;


              if(iKeyToWatch == val(data[10])){
                stm << KMessageTestKeyPressed;

                
              }else{

                stm << KMessageAnotherKeyPressedWhenTesting ;
              }
             
              iTestKey = false;
             

              write(iWritePipeInt,stm.str().c_str(),1);
            }
            CSync::Unlock();
            
          }
          
        }
      
      }else{
        
        ownSleep_ms(200);
      }
    }
  }else if(aThreadNumber == 1){
    char buf;
    while(iThreadRunning){
      dPrint(1,"thread 1...")
      struct pollfd pfds[1] = {{ iReadPipeInt, POLLIN, 0 }};
      int result = poll(pfds, 1, 1000);
      if (result < 0) {
        dPrintLE(3,"poll() failed for 'read' file descriptor (%d)",
                 iReadPipeInt);
        
      }else if(result > 0){
        if(read(iReadPipeInt,&buf,1) >0){
          if(atoi((const char *)&buf) == KCommandBindKey){

            Lock();
            iKeyBinded = false;
            Unlock();
            dPrint(1,"binding key..");
            BindKeyToWatch();
            std::ostringstream stm;
            stm << KMessageKeyBinded;
          
            write(iWritePipeInt,stm.str().c_str(),1);
          }else if(atoi((const char *)&buf) == KCommandTestKey){
            if(iKeyBinded){

              
              Lock();
              iTestKey = true;
             
              Unlock();
                          
            }

          }
        }

      }


    }
        
    
  }
  return 0;
}

int CKeyWatcher::val(char c) {
  if((int) c < 0) {
    return (int) c + 256;
  } else {
    return (int) c;
  }
}

void CKeyWatcher::ReadEventLine(char * data){
  int i;
  dPrint(1,"Reading event line, %d",iInput);
  for(i = 0; i <= 15; i++) {
    data[i] = (char) fgetc(iInput);
  }
  
}
 
bool CKeyWatcher::IsRunning(){
   
 
  return iThreadRunning;
}
 

